#ifndef TINY_MUDUO_CHANNEL_H_
#define TINY_MUDUO_CHANNEL_H_

#include <sys/epoll.h>
#include <utility>

#include "eventloop.h"
#include "callback.h"

namespace tiny_muduo {

enum ChannelState {
	kNew,
	kAdded,
	kDeleted
};
class Channel
{
public:
	Channel(EventLoop* loop, const int& fd);
	~Channel();

	void HandleEvent();

	void SetReadCallback(const ReadCallback& callback) { 
		read_callback_ = callback; 
	}

	void SetWriteCallback(const WriteCallback& callback) {
		write_callback_ = callback;
	}

	void EnableReading() {
		events_ |= (EPOLLIN | EPOLLPRI | EPOLLET); 
		Update();  
	}

	void EnableWriting() {
		events_ |= EPOLLOUT;
		Update();
	}

	void DisableAll() {
		events_ = 0;
		Update(); 
	}

	void DisableWriting() {
		events_ &= ~EPOLLOUT;
		Update();  
	}

	void Update() {
		loop_->Update(this);
	}

	void RemoveFd() {
	}

	void SetReceivedEvents(int events) {
		recv_events_ = events;
	}

	void SetChannelState(ChannelState state) {
		state_ = state;
	}

	int fd()  { return fd_; } 
	int events()  { return events_; }
	int recv_events() { return recv_events_; }
	ChannelState state() { return state_; }
	bool IsWriting() { return events_ & EPOLLOUT; }
	bool IsReading() { return events_ & (EPOLLIN | EPOLLPRI); }

	
private:
	EventLoop* loop_;
	int fd_;
	int events_;         // update events
	int recv_events_;    // epoll received events
	
	ChannelState state_;
	ReadCallback read_callback_;
	WriteCallback write_callback_;  
};

}
#endif

